﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using CsvHelper;


namespace AIC_Notification
{
    public class StudentDB
    {
        public IList<Student> Students = null;

        private ApplicationType AppType;
        private List<StudentAdmissionResult> Results = null;
        private IList<StudentScore> Scores = null;

        public StudentDB(ApplicationType Type)
        {
            AppType = Type;
        }

        public bool Initialize()
        {
            string StudentFileName = "";

            try
            {
                if (AppType == ApplicationType.sof)
                {
                    StudentFileName = Global.InputDirectory + Global.config.SOF_StudentFileName;
                }
                else if (AppType == ApplicationType.guidance)
                {
                    StudentFileName = Global.InputDirectory + Global.config.Guidance_StudentFileName;
                }
                else
                {
                    Global.SysUtil.Log(String.Format("Unsupported Application Type"), 2);
                    return false;
                }

                using (StreamReader sr = new StreamReader(StudentFileName))
                {
                    //Csv reader reads the stream
                    CsvReader csvread = new CsvReader(sr);
                    csvread.Configuration.RegisterClassMap<StudentMap>();
                    csvread.Configuration.HeaderValidated = null;

                    //csvread will fetch all record in one go to the IEnumerable object record
                    Students = csvread.GetRecords<Student>().ToList();

                    sr.Close();
                }
            }
            catch (Exception ex)
            {
                Global.SysUtil.Log(String.Format("Failed to read from student file: {0}", StudentFileName), 2);
                Global.SysUtil.Log(ex.ToString(), 2);
                return false;
            }

            // Load admission result information from CSV from Salesforce
            try
            {
                using (StreamReader sr = new StreamReader(Global.InputDirectory + "Results.csv"))
                {
                    //Csv reader reads the stream
                    CsvReader csvread = new CsvReader(sr);
                    csvread.Configuration.RegisterClassMap<ResultMap>();
                    csvread.Configuration.HeaderValidated = null;

                    //csvread will fetch all record in one go to the IEnumerable object record
                    Results = csvread.GetRecords<StudentAdmissionResult>().ToList();

                    sr.Close();
                }
            }
            catch
            {
                Global.SysUtil.Log(String.Format("Failed to read from Results file: {0}", "Results.csv"), 2);
                return false;
            }

            // Load student score information from CSV from Salesforce
            try
            {
                using (StreamReader sr = new StreamReader(Global.InputDirectory + "Scores.csv", true))
                {
                    //Csv reader reads the stream
                    CsvReader csvread = new CsvReader(sr);
                    csvread.Configuration.RegisterClassMap<StudentScoreMap>();
                    csvread.Configuration.HeaderValidated = null;

                    //csvread will fetch all record in one go to the IEnumerable object record
                    Scores = csvread.GetRecords<StudentScore>().ToList();

                    sr.Close();
                }
            }
            catch
            {
                Global.SysUtil.Log(String.Format("Failed to read from Scores file: {0}", "Scores.csv"), 2);
                return false;
            }

            // Connect Objects
            foreach (var Student in Students)
            {
                Student.ResultListObject = Results.FindAll(StudentAdmissionResult => StudentAdmissionResult.StudentID.Equals(Student.Id));
                Student.ScoreObject = Scores.SingleOrDefault(StudentScore => StudentScore.StudentID.Equals(Student.Id));
                if (Student.ScoreObject != null)
                {
                    // Student.ScoreObject.PopulateGPA();
                    Student.ScoreObject.PopulateSAT2andAP();
                }
            }

            return true;
        }

        public void ReadFromJson(string filename)
        {
            using (StreamReader sr = new StreamReader(filename))
            {
                string temp = sr.ReadToEnd();
                Students = JsonConvert.DeserializeObject<IList<Student>>(temp);
            }
        }

        public void WriteToJson(string filename)
        {
            // Write Students Object to Json
            using (StreamWriter sw = new StreamWriter(filename))
            {
                string temp = JsonConvert.SerializeObject(Students, Formatting.Indented);
                sw.WriteLine(temp);
            }
        }
    }
}
